/**
 *
 */
package org.easley.pay.common;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;

/**
 * 服务接口响应类
 *
 * @author Ternence
 * @date 2017年5月9日
 */
public final class ApiResult<T> implements Serializable {

    private static final Logger LOGGER = LoggerFactory.getLogger(ApiResult.class);

    /**
     * 成功返回码
     */
    public static final String RESULT_CODE_SUCCESS = "0";

    /**
     * 未知错误返回码
     */
    public static final String RESULT_CODE_FAIL = "-1";



    /**
     *
     */
    private static final long serialVersionUID = 1L;

    /**
     * <pre>
     * 返回码
     * 0：成功（默认值）
     * 其他：失败
     * </pre>
     */
    private String code = RESULT_CODE_SUCCESS;

    /**
     * 响应消息内容，可存放错误提示消息或成功消息
     */
    private String message;

    /**
     * 响应对象
     */
    private T entry;

    /**
     * 降级标示
     */
    public static final String DEGRADE = "-100000000000";

    public static boolean isDegrade(ApiResult apiResult){
        return apiResult !=null && DEGRADE.equals(apiResult.getCode());
    }

    private ApiResult() {

    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getEntry() {
        return entry;
    }

    public void setEntry(T entry) {
        this.entry = entry;
    }

    /**
     * 构建一个新的实例
     *
     * @return
     * @date 2017年5月9日
     * @author Ternence
     */
    public static <T> ApiResult<T> build() {
        return new ApiResult<>();
    }

    public static <T> ApiResult<T> build(Class<T> clazz) {
        return new ApiResult<T>();
    }

    /**
     * 描述 构建一个新的实例并实例化一个返回对象
     *
     * @param clazz
     * @author: WilliamZhu
     * @Time: 11:09  2018/12/6 0006
     */
    public static <T> ApiResult<T> setContent(Class<T> clazz ) {
        ApiResult<T> apiResult = new ApiResult<>();
        try {
            apiResult.setEntry(clazz.newInstance());
        } catch (InstantiationException e) {
            LOGGER.warn("ApiResult.setContent发生InstantiationException异常", e);
        } catch (IllegalAccessException e) {
            LOGGER.warn("ApiResult.setContent发生IllegalAccessException异常", e);
        }
        return apiResult;
    }

    /**
     * 构建一个具有返回对象的实例
     *
     * @param obj
     * @return
     * @date 2017年5月9日
     * @author Ternence
     */
    public static <T> ApiResult<T> build(T obj) {
        ApiResult<T> result = new ApiResult<>();
        result.setEntry(obj);
        return result;
    }

    /**
     * 判断返回结果中响应码是否成功
     *
     * @return
     * @date 2017年5月9日
     * @author Ternence
     */
    public boolean isSuccess() {
        return RESULT_CODE_SUCCESS.equals(code);
    }

    /**
     * 返回错误信息，标记响应码为-1
     *
     * @param message
     * @return
     * @date 2017年5月9日
     * @author Ternence
     */
    public ApiResult<T> error(String message) {
        return error(RESULT_CODE_FAIL, message);
    }


    /**
     * 返回错误信息，标记响应码为具体的错误码
     *
     * @param code
     * @param message
     * @return
     * @date 2017年5月9日
     * @author Ternence
     */
    public ApiResult<T> error(String code, String message) {
        this.code = code;
        this.message = message;
        return this;
    }

    /**
     * 判断返回结果是否失败
     *
     * @param result 返回结果对象
     * @return 如果失败, 则返回true；否则返回false
     * @date 2017年5月18日
     * @author Ternence
     */
    public static boolean isFail(ApiResult<?> result) {
        return result == null || !result.isSuccess();
    }

    /**
     * 判断返回结果是否成功
     *
     * @param result 返回结果对象
     * @return 如果成功, 则返回true；否则返回false
     * @date 2017年5月24日
     * @author Ternence
     */
    public static boolean isSuccess(ApiResult<?> result) {
        return result != null && result.isSuccess();
    }


    /**
     * 判断返回结果是否全部成功
     *
     * @param result 返回结果对象
     * @author: WilliamZhu
     * @Time: 13:31  2018/12/4 0004
     */
    public static boolean isAllSuccess(ApiResult<?> result) {
        return null != result && result.isSuccess() && null != result.getEntry();
    }

    public static boolean isNotAllSuccess(ApiResult<?> result){
        return !isAllSuccess(result);
    }

    public String toString() {
        return JSON.toJSONString(this);
    }


    public static String getErrorMsg(ApiResult<?> result) {
        if(isSuccess(result)){
            return StringUtils.EMPTY;
        }
        if(result == null){
            return StringUtils.EMPTY;
        }
        return result.getMessage();
    }
}
